////////////////////////////////////////////////////////////////////////
//
// BEGIN_COPYRIGHT
// Confidential property of Faxsun.
//
// Copyright 2014-
//
// Faxsun. All rights reserved.
//
// Unpublished rights reserved under Chinese copyright laws.
// END_COPYRIGHT
//
// BEGIN_DISCLAIMER
// This software contains confidential and trade secret information of 
// Faxsun. Use, duplication or disclosure of the software and 
// documentation by any individual, organization or government must be 
// granted written agreement from Faxsun.
//
// Faxsun. Shanghai China
// END_DISCLAIMER
//
////////////////////////////////////////////////////////////////////////

package com.faxsun.web.aspect;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import mtons.modules.pojos.UserContextHolder;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.stereotype.Component;

import com.faxsun.core.persist.entity.TracePO;
import com.faxsun.core.pojos.DeviceId;
import com.faxsun.core.pojos.enums.TraceType;
import com.faxsun.web.pojos.FSUserProfile;
import com.faxsun.web.utils.MobileDetect;

/**
 * Aspect for normal browse trace functionality.
 * 
 * @author leima
 */
@Aspect
@Component
public class BrowseTraceAspect {
    
    @Pointcut("within(com.faxsun.web.controller.product.ProductController)")
    public void inProductController() {
    }    
    @Pointcut("within(mblog.web.controller.front.posts.PostController)")
    public void inPostController() {
    }
    @Pointcut("execution(public * view*(..))")
    public void anyBrowseOperation() {
    }
    
    @Around(" (inProductController() || inPostController()) && anyBrowseOperation() ")
    public Object afterBrowseMethodInTraceController(final ProceedingJoinPoint pjp) {
        FSUserProfile up = (FSUserProfile) UserContextHolder.getUserProfile();
        if(up != null){
            Object[] args = pjp.getArgs();            
            long id = (long) args[0]; 
            
            String url = "";
            final Signature signature = pjp.getStaticPart().getSignature();
            if(signature instanceof MethodSignature){
                final MethodSignature ms = (MethodSignature) signature;
                @SuppressWarnings("rawtypes")
				Class cls = ms.getDeclaringType();
                String mName = ms.getName();
                if(cls.getCanonicalName().contains("ProductController") && mName.contains("viewProduct")){
                    url = "/product/view/" + id;                    
                    TracePO tpo = assemble(url, up);                                
                    TraceAsyncHandler.traceQueue.add(tpo);
                }else if(cls.getCanonicalName().contains("PostController") && mName.contains("view")){
                    url = "/post/view/" + id;                    
                    TracePO tpo = assemble(url, up);                                
                    TraceAsyncHandler.traceQueue.add(tpo);
                }
            }
        }
        
        Object ret = null;
        try {
            ret = pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return ret;
    }
    
    private TracePO assemble(String data, FSUserProfile up){
        TracePO tpo = new TracePO();
        tpo.setTraceData(data);
        tpo.setTraceType(TraceType.BROWSE.getIntValue());
        tpo.setUserId(up.getId());
        tpo.setTraceTime(new Date());
        
        HttpServletRequest request = MobileDetect.getRequest();
        if(request != null){                
            DeviceId did = new DeviceId();                
            
            String ip = MobileDetect.getClientIp(request);
            if(ip != null){
               did.addValue(DeviceId.IP, ip);                    
            }
            
            Device d = DeviceUtils.getCurrentDevice(request);
            if(d != null){
               boolean mobile = d.isMobile();
               boolean pc = d.isNormal();
               boolean tablet = d.isTablet();  
               if(mobile){
                  did.addValue(DeviceId.DEVICE_TYPE, "MOBILE");
               }else if(pc){
                  did.addValue(DeviceId.DEVICE_TYPE, "PC");                       
               }else if(tablet){
                  did.addValue(DeviceId.DEVICE_TYPE, "TABLET");
               }
            }
            
            tpo.setDeviceId(did.toString());
        }
        return tpo;
    }
}
